package com.ht.api.wwx;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

import com.tencent.wework.Finance;

import lombok.extern.slf4j.Slf4j;

/**
 * 企业微信会话存档工具类
 * @author asq
 * @createTime 2025年2月26日 20:30:20
 */
@Slf4j
public class WXChatUtil {
	/** 企业微信SDK实例 */
    private static long sdk;
    
    private static final String corpId = "ww669ca452439131bc";
    private static final String secretKey = "-qgncw_3esse1ZIIDqOVkwMSqGaWTT9UkhY5z2wgMhc";
    private static final String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDgDIA3J6RyMvt42bn/0DwUOchvlH9IMKCKSe/YmTX/HEGNcvWzfQq/cgDSxstV/FgaUtAgNXMmSTihaG8dIAB6/daO/1pHldLo+fKzFIVuX6XExuEIFbfPOUSbNzgXS0JmlXd9n0pySQjb4gg8oEla+mds0OIWBKE9UUZtP2KxwasJ7Bip9P0dcuybr+Sce7i6NZflz5Ovp3wysXKG4oOHKgr6wkeNabnYvf0ZcujomCK+hPv9vCe6YG3Kn/ojUgStBkLQ/IMvmf7gh7dnaIdAozy5J/MzSGP+qunIkRPze87jYUNxkXn1ufkuM1q9m8AuxD1PYex/hhKUKRchY3TXAgMBAAECggEAcWWiV0gXMT2gjbAVNeadIdeFHQRZz53dA2EcpdIVxEL24rK2rNuy3ubCh+vZ6nFH3jrf4A1tdIlGwlrrMiCKXbWwLLwNY4HvN7+aGQ1f41dBvXCzYLYtTBK+KJkwKIoM14L68Xf35BQXCcNDS/wMZKGsSyUF6QL64OAL9ytHtpNOkwcpecVBRWvyBueCxaHiKLhQLWUBnaXG1jgx28RnjQXFM7yS7MG7MW8sBovhH22cc18gnh2FI0pjoIyCwHIfA3w6r/mpJreaBh7xu03VqUzD3Uee/PB+fdYtC9NvsGQ0O30eHmCrNtNt+Mpu46ilKxyJMp7Ui2Qp+ZRA5EqS4QKBgQD005NaYtAFjhoIYPT7wPHjN/zGk1wXnQmSQthvxY7fvMSeU+qozzX3vq9v3JXT+UKEPUUQ8UYhyChAhko4K/krVD+tJUixIeWg5qCd9HiF5w+nY0dLWxhSO3aaigqegYYHnJbrkEl1glGXOer3fTOBB3TSGCqlNnIzfxbcTOYIXwKBgQDqRiuTIMvxEl72RGGGOwC0mGJFVqvc/O85mamfbVrWjCJS8JR8Q9LKvJtQPQDVUIbn9Jp6pvh9sIduhYTDu+HcINPPyMfNDKogpw1dkIP6sDqWghrIv7nt7xE3sH+MHxZD/7LqPp1RXteuznpPG30f7dxvtsaa0keOCCJnGGFGiQKBgBpinvPTyGWA3g9fG6fyMF9zjjt8cCVfWEO6DodlPDOirXH+y0BsLH3JwDCHDmKs710/GS1tQ0iqwKPLlT4ehxkDWGV5qi7k31GK6W58hWyw7T/19B4L8EAUhoC7Nc/FV8OEPcOfZjtS0yZAKLGJfb5/JjjqP9ZUWtRv8u/FHdlzAoGAcFPKytWb02/KhmvNEu4xbWXvIG3pI6FHFqgd02o8dshkIL5ng5mFdV2vXm6RerYMqST3+L0cQi+lEBIG0U7Bgalfxa3wVtmurM9MMkN7dHSQ8t9Y9k4vWO0apUgEL+wr4di1MWlqRryhz5gCvvFgMjH7UrkhStRuKKSv0hy3b3kCgYBDujjLZg7BKd6W6j0WwgmiZERUfa0VjvALP+8F66q4PhI+Ir1ndDnFQWoidLCmv7xmTq9MpebCGab2yXNvEOL/yv52Pl2v0hJBJOmGfATCLbxLO5n1xrKicPRAl6M0hZ0jhfSMxojHJdnbgooSpXFoTTJucHw4YXulLWY0uGDzBA==";
 
    static {
        try {
            log.info("[会话存档sdk]初始化开始...");
            sdk = Finance.NewSdk();
            log.info("[会话存档sdk]NewSdk,sdk:{}", sdk);
            long ret = Finance.Init(sdk, corpId, secretKey);
            log.info("[会话存档sdk]Init,ret:{}", ret);
            if (ret != 0) {
                Finance.DestroySdk(sdk);
                String error = "[会话存档sdk]初始化SDK失败，错误码：" + ret;
                log.error(error);
                throw new RuntimeException(error);
            }
            log.info("[会话存档sdk]初始化成功");
        } catch (Throwable e) {
            String error = "[会话存档sdk]初始化SDK失败：" + e.getMessage();
            log.error(error, e);
            throw new RuntimeException(error, e);
        }
    }
    
    /**
     * 拉取会话存档
     * @param seq 存档消息序号，拉取序号建议设置为上次拉取返回结果中最大序号。首次拉取时seq传0，sdk会返回有效期内最早的消息
     * @return
     */
    public static String queryChatMsgList(int seq) {
        try {
        	long slice = Finance.NewSlice();
            try {
            	long ret = Finance.GetChatData(sdk, seq, 1000, "", "", 5, slice);
    	        if (ret != 0) {
    	            Finance.FreeSlice(slice);
    	            return null;
    	        }
    	        return Finance.GetContentFromSlice(slice);
            } finally {
                Finance.FreeSlice(slice);
            }
        } catch (Exception e) {
        	log.error("[会话存档sdk]拉取会话存档出错：{}", e.getMessage(), e);
            throw new RuntimeException("拉取会话存档出错：" + e.getMessage(), e);
        }
    }
    
    /**
     * 解密聊天消息
     * @param encryptRandomKey 加密的随机密钥
     * @param encryptChatMsg 加密的聊天消息
     * @return 解密后的消息内容
     */
    public static String decryptChatMsg(String encryptRandomKey, String encryptChatMsg) {
        try {
            String decryptedKey = decryptRandomKey(encryptRandomKey);
            long slice = Finance.NewSlice();
            try {
                long ret = Finance.DecryptData(sdk, decryptedKey, encryptChatMsg, slice);
                if (ret != 0) {
                    throw new RuntimeException("解密消息失败，错误码：" + ret);
                }
                return Finance.GetContentFromSlice(slice);
            } finally {
                Finance.FreeSlice(slice);
            }
        } catch (Exception e) {
        	log.error("[会话存档sdk]解密聊天消息出错：{}", e.getMessage(), e);
            throw new RuntimeException("解密聊天消息出错：" + e.getMessage(), e);
        }
    }
    
    /**
     * 解密随机密钥
     */
    private static String decryptRandomKey(String encryptRandomKey) {
        try {
            byte[] str1 = Base64.getDecoder().decode(encryptRandomKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            
            String formattedPrivateKey = privateKey.replaceAll("\\s+", "");
            byte[] privateKeyBytes = Base64.getDecoder().decode(formattedPrivateKey);
            
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            PrivateKey priKey = keyFactory.generatePrivate(keySpec);
            
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            
            byte[] str2 = cipher.doFinal(str1);
            return new String(str2);
        } catch (Exception e) {
        	log.error("[会话存档sdk]解密random_key失败：{}", e.getMessage(), e);
            throw new RuntimeException("解密random_key失败：" + e.getMessage(), e);
        }
    }
    
    /**
     * 确保在JVM关闭时释放资源
     */
    @Override
    protected void finalize() throws Throwable {
        try {
        	Finance.DestroySdk(sdk);
        } finally {
            super.finalize();
        }
    }
    
    // 使用示例
    public static void main(String[] args) {
        String encryptRandomKey = "jeW6rn8KIOY8TKO1SMngMQNKdUFpcgmf2ldszJPplPELAQLE1eHdJw6IogAGejcfAYcswXqxLA7DXqiRv7k63fnahH2+9WOa2Tp0pKnp6ENQogrvJ3qYhyBwYUJAWzUZwXG2+bvybql5W8dk4J6U/cc5orL6JhiCZj6hHmqicEAeusn2RkJ3E7lHQEd1nKRoKreeOzpmVQueFttOqzu93U695QodKv4VfTnDa+9TFWEAta45Kv5uVKWtm0AvGQp83IqybIj3GJb25qZTgnz5lZD9I5xr+Qtji4VX06n/w1+lfwbEwKqvVythb1R0gUx842NladRNDeGGqJqIZ/gExg==";
        String encryptChatMsg = "YR8jJBiSlfkcWcqJBNgrF1MxDprZuhwywLb9sGF6f6xax22+I/rVlW5rFMb3WaFbLG85dB/7oMbYlcJcrpzPQXWfFkL07RYLgFDzARzLp7yTRhgAbNDvu/sMf9lyeFxi6v3Ux4AxS0chKPHkWYUqnbrZeDQ7gUrm+aZtwXrnZx/iKdz7c81Wvd2eB4ePYXmV1c5nBTqeKuL5ps8oIpEPCvA5QxIZ6gl+GrkeiykLJKQ0GZLnRQ8027sW5NYebRXU9TeDvzwvPkkdPv12zSfWP7SyyIFVyZza1ybSKWxxklKbLSCYnP79Wm/GgXQwJYinyOt96hfkBo8khI7DdKoYVM4D/Sz0/ihPSVq4c7eMzXeFTDe4ji1uhPHCkRA4DCZwJOYC9Uf70nXIKF37A5dfNduzvu4OyDVNeU2UJxtEA=sXaqalL64HyXds/";
        
        String decryptedMsg = WXChatUtil.decryptChatMsg(encryptRandomKey, encryptChatMsg);
        System.out.println("解密后的消息：" + decryptedMsg);
    }
}